'use strict'

class DBHelper {
    #db = null;
    #request = null;
    #version = 1;
    #dbName = "music";
    #tableName = "user";
    #timestamp = 0;
    #callback = null;

    constructor(callback) {
        this.#callback = callback;
        this.#open();
        this.#timestamp = new Date().getTime();
    }

    #open() {
        const indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
        this.#request = indexedDB.open(this.#dbName, this.#version);
        this.#request.onsuccess = this.#openSuccess.bind(this)
        this.#request.onerror = this.#openError.bind(this)
        this.#request.onupgradeneeded = this.#onupgradeneeded.bind(this)
    }

    #onupgradeneeded(e) {
        console.info("upgrade", e);
        this.#db = e.target.result;
        this.#db.createObjectStore(this.#tableName, {keyPath: "hash"});
    }

    #openSuccess(e) {
        console.info("success", e);
        this.#db = e.target.result;
        if (this.#callback) {
            this.#callback();
        }
    }

    #openError(e) {
        console.error(e);
    }

    reportTimeStamp() {
        console.log(this.#timestamp);
    }

    insert(record) {
        return new Promise((resolve, reject) =>{
            try {
                // use put will overwrite if key exists, add will not
                let request = this.#db.transaction([this.#tableName], 'readwrite').objectStore(this.#tableName).put(record);
                request.onsuccess = function(e) {
                    resolve(e);
                }
                request.onerror = function(e) {
                    reject(e);
                }
            } catch(e) {
                reject(e);
            }
        });
    }

    get(key) {
        return new Promise((resolve, reject) => {
            try {
                let request = this.#db.transaction([this.#tableName]).objectStore(this.#tableName).get(key);
                request.onsuccess = function(e) {
                    resolve(request.result);
                }
                request.onerror = function(e) {
                    reject(e);
                }
            } catch(e) {
                reject(e);
            }
        });
    }

    update(record) {
        //
    }

    remove(key) {
        return new Promise((resolve, reject) => {
            try {
                let request = this.#db.transaction([this.#tableName], "readwrite").objectStore(this.#tableName).delete(key);
                request.onsuccess = function(e) {
                    resolve(request.result);
                }
                request.onerror = function(e) {
                    reject(e);
                }
            } catch(e) {
                reject(e);
            }
        });
    }

    download(record) {
        //
    }
}

var DB = (function() {
    var instance;
    return {
        getInstance: function(callback) {
            if (!instance) {
                instance = new DBHelper(callback);
            }
            return instance;
        }
    };
})();
